#include "StdAfx.h"
#include "BinaryJsonObjectBuilder.h"
#include "BinaryJsonObject.h"
#include "BinaryJsonObjectIterator.h"
#include "BinaryJsonElement.h"
#include <boost/lexical_cast.hpp>
BinaryJsonObjectBuilder& BinaryJsonObjectBuilder::appendElements(BinaryJsonObject x) {
	BinaryJsonObjectIterator it(x);
	while ( it.moreWithEOO() ) {
		BinaryJsonElement e = it.next();
		if ( e.eoo() ) break;
		append(e);
	}
	return *this;
}

BinaryJsonObjectBuilder& BinaryJsonObjectBuilder::appendElementsUnique(BinaryJsonObject x) {
	std::set<std::string> have;
	{
		BinaryJsonObjectIterator i = iterator();
		while ( i.more() )
			have.insert( i.next().fieldName() );
	}

	BinaryJsonObjectIterator it(x);
	while ( it.more() ) {
		BinaryJsonElement e = it.next();
		if ( have.count( e.fieldName() ) )
			continue;
		append(e);
	}
	return *this;
}
bool BinaryJsonObjectBuilder::appendAsNumber( const StringData& fieldName , const string& data ) {
	if ( data.size() == 0 || data == "-" || data == ".")
		return false;

	unsigned int pos=0;
	if ( data[0] == '-' )
		pos++;

	bool hasDec = false;

	for ( ; pos<data.size(); pos++ ) {
		if ( isdigit(data[pos]) )
			continue;

		if ( data[pos] == '.' ) {
			if ( hasDec )
				return false;
			hasDec = true;
			continue;
		}

		return false;
	}

	if ( hasDec ) {
		double d = atof( data.c_str() );
		append( fieldName , d );
		return true;
	}

	if ( data.size() < 8 ) {
		append( fieldName , atoi( data.c_str() ) );
		return true;
	}

	try {
		long long num = boost::lexical_cast<long long>( data );
		append( fieldName , num );
		return true;
	}
	catch(boost::bad_lexical_cast &) {
		return false;
	}
}
BinaryJsonObjectIterator BinaryJsonObjectBuilder::iterator() const {
	const char * s = _b.buf() + _offset;
	const char * e = _b.buf() + _b.len();
	return BinaryJsonObjectIterator( s , e );
}